using System;
using System.Collections.Generic;

using log4net;

using GymManager.Exception;
using GymManager.Mechanism;
using GymManager.Persistence.DAO;
using GymManager.Persistence.VO;

namespace GymManager.Business
{
    /// <summary>
    /// Class responsible by providing services regarding users
    /// </summary>
    public class UserServices
    {
        // logger instance
        private ILog _logManager = LogManager.GetLogger(typeof(UserServices));

        /// <summary>
        /// Method responsible by getting information about user in according to a given login
        /// </summary>
        /// <param name="String">user's login</param>
        /// <returns>User - user value object matching with given login</returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public User findByLogin(String user)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }
            
            User userResult = null;

            try
            {
                // searching user
                UserDAO userDAO = new UserDAO();
                userResult = userDAO.findByLogin(user);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }            
            
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return userResult;
        }

        /// <summary>
        /// Method responsible by getting information about user considering a given filter
        /// </summary>
        /// <param name="String">user's login</param>
        /// <param name="Role">user's role</param>
        /// <param name="Boolean">user's active status</param>
        /// <returns>IList - list of user value objects</returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<User> findByAny(String login, Role role, Boolean isActive)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // user list result
            IList<User> userList = null;

            try
            {
                // building value object to be used as filter
                User userVO = new User();
                userVO.Role = role;
                userVO.IsActive = isActive;

                if (!String.IsNullOrEmpty(login))
                {
                    userVO.Login = "%" + login + "%";
                }

                // searching users
                UserDAO userDAO = new UserDAO();
                userList = userDAO.findByAny(userVO);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return userList;
        }

        /// <summary>
        /// Method responsible by getting all active users
        /// </summary>
        /// <returns>IList - list of user value objects</returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<User> findAllActive()
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // user list result
            IList<User> userList = null;

            try
            {
                UserDAO userDAO = new UserDAO();
                userList = userDAO.findAllActive();
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return userList;
        }

        /// <summary>
        /// Method responsible by adding a new user to database
        /// </summary>
        /// <param name="User">user information to be saved</param>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public void create(User userVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // encrypt password before inserting user
                userVO.Password = CriptographyManager.encrypt(userVO.Password);
                
                // adding user to database
                UserDAO userDAO = new UserDAO();
                userDAO.create(userVO);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by removing an user from database
        /// </summary>
        /// <param name="Int32">user identifier</param>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public void remove(Int32 userId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // removing user from database
                UserDAO userDAO = new UserDAO();
                userDAO.remove(userId);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by updating an user in database
        /// </summary>
        /// <param name="User">user information to be saved</param>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public void update(User userVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // encrypt password before updating user
                userVO.Password = CriptographyManager.encrypt(userVO.Password);

                // adding user to database
                UserDAO userDAO = new UserDAO();
                userDAO.update(userVO);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }
    }
}
